/**
  ******************************************************************************
  * File Name          : terminal.c
  * Description        : Code for terminal applications
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "tskcfg.h"
#include "lora.h"
#include "bsp.h"
#include "syscfg.h"
#include "collector.h"
#include "storage.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define TTYRECV_QUE_LENGTH         3
#define TTYRECV_QUE_ITEMSIZE       (sizeof(uint8_t) * TTY_RXBUF_MAXLEN)

typedef enum
{
	TTY_HEADER1  = 0u,
	TTY_HEADER2,
	TTY_PAYLOAD,
	TTY_0A,
}tty_recvstattype;

QueueHandle_t        TTYRecv_qhd;
static StaticQueue_t ttyrecv_stru;
static uint8_t       ttyrecv_area[ TTYRECV_QUE_LENGTH * TTYRECV_QUE_ITEMSIZE ];

TaskHandle_t xTerminal_Thd = NULL;
StaticTask_t xTerminal_Tcb;
StackType_t  xTerminal_Stk[ TTY_STACK_SIZE ];

static volatile	tty_recvstattype tty_recv_stat;
static char tty_isrbuf[TTY_RXBUF_MAXLEN];
static char tty_rcvbuf[TTY_RXBUF_MAXLEN];


static void cmd_id(const char *buf)
{
  uint8_t err;
  
  if(strcmp(buf, ROUTE_SELF_DID) == 0)
  {
    _printf("ID::same did\r\n");
    return;
  }
  
  err = Route_ParseDID(buf, NULL);
	if(err != 0)
	{
		_printf("ID::error--%d\r\n", err);
		return;
	}
  
  _printf("ID::success--%s\r\n", buf);
  
  Route_RefreshDeviceList(buf);
}

void cmd_bdtm(const char *buf)
{
	Route_485_broadtime();
}

static void cmd_dbg(const char *buf)
{
  if(buf[0] == '1')
  {
    Sys_DebugSwitch.net_tx_tp = 1;
  }
  else
  {
    Sys_DebugSwitch.net_tx_tp = 0;
  }
  
  if(buf[1] == '1')
  {
    Sys_DebugSwitch.net_tx_pl = 1;
  }
  else
  {
    Sys_DebugSwitch.net_tx_pl = 0;
  }
  
  if(buf[2] == '1')
  {
    Sys_DebugSwitch.net_rx_tp = 1;
  }
  else
  {
    Sys_DebugSwitch.net_rx_tp = 0;
  }
  
  if(buf[3] == '1')
  {
    Sys_DebugSwitch.net_rx_pl = 1;
  }
  else
  {
    Sys_DebugSwitch.net_rx_pl = 0;
  }
  
  _printf("net_tx_tp:%d\r\n",Sys_DebugSwitch.net_tx_tp);
  _printf("net_tx_pl:%d\r\n",Sys_DebugSwitch.net_tx_pl);
  _printf("net_rx_tp:%d\r\n",Sys_DebugSwitch.net_rx_tp);
  _printf("net_rx_pl:%d\r\n",Sys_DebugSwitch.net_rx_pl);
}

static void cmd_adddev(const char *buf)
{
	Storage_SaveType sftype;
	uint32_t v1, v2;
	
	v1 = strlen(buf);
	if( (v1 > 5) || (v1 < 3) )
	{
		_printf("DEV Error!\r\n");
		return;
	}
	
	v1 = atoi(buf);
	if( v1 > COLLECTOR_LORADEV_MAXNUM )
	{
		_printf("DEV Error!\r\n");
		return;
	}
	
	v2 = atoi(strchr(buf, ',')+1);
	if( v2 > COLLECTOR_LORADEV_MAXNUM )
	{
		_printf("DEV Error!\r\n");
		return;
	}
	
	SysCfg_RunPara.lora_num = v1;
	SysCfg_RunPara.rs485_num = v2;
	
	if(Storage_qhd != NULL)
	{
		sftype = SFLASH_SAVE_SYSCFG;
		xQueueSend(Storage_qhd, &sftype, 1000);
	}
	
	_printf("Lora activated devices:%d\r\n", SysCfg_RunPara.lora_num);
	_printf("RS485 activated devices:%d\r\n", SysCfg_RunPara.rs485_num);
}

void cmd_temp(const char* buf)
{
	Collector_LocalData.average.temperature = atoi(buf);
	_printf("average:%d\r\n", Collector_LocalData.average.temperature);
}

void vTerminal_Task( void * pvParameters )
{
	const char *p;
	TTYRecv_qhd = xQueueCreateStatic(TTYRECV_QUE_LENGTH,
	                                 TTYRECV_QUE_ITEMSIZE,
	                                 ttyrecv_area,
	                                 &ttyrecv_stru);
	while(1)
	{
		if(xQueueReceive(TTYRecv_qhd, &tty_rcvbuf, 5000) == pdTRUE)
		{
			p = strstr( tty_rcvbuf, "ID:");
			if( p != NULL)
			{
				cmd_id(p+3);
			}
			
			p = strstr( tty_rcvbuf, "DEV:");
			if( p != NULL)
			{
				cmd_adddev(p+4);
			}

      p = strstr( tty_rcvbuf, "BDTM");
			if( p != NULL)
			{
				cmd_bdtm(p+5);
			}

      p = strstr( tty_rcvbuf, "DBG:");
			if( p != NULL)
			{
				cmd_dbg(p+4);
			}
      
      p = strstr( tty_rcvbuf, "GCSQ");
			if( p != NULL)
			{
        Route_gwcfg_local_config_getcsq();
      }
      
			p = strstr( tty_rcvbuf, "TEMP:");
			if( p != NULL)
			{
				cmd_temp(p+5);
			}
			
			p = strstr( tty_rcvbuf, "TIME");
			if( p != NULL)
			{
				_printf("%04d-%02d-%02d %02d:%02d:%02d\r\n", Sys_Runtime.year+2000, Sys_Runtime.month,\
																										 Sys_Runtime.day, Sys_Runtime.hour,\
																										 Sys_Runtime.minute, Sys_Runtime.second);
			}
		}
	}
}

void Terminal_RecvIsr(uint8_t dat)
{
	static uint32_t count;
	
	switch(tty_recv_stat)
	{
		case TTY_HEADER1:
			if(dat == ';')
			{
				tty_recv_stat = TTY_HEADER2;
			}
			break;
		
		case TTY_HEADER2:
			if(dat == ';')
			{
				tty_recv_stat = TTY_PAYLOAD;
				count = 0;
			}
			else
			{
				tty_recv_stat = TTY_HEADER1;
			}
			break;
		
		case TTY_PAYLOAD:
			if(dat == 0x0du)
			{
				tty_recv_stat = TTY_0A;
			}
			else
			{
				tty_isrbuf[count++] = dat;
				if(count > (TTY_RXBUF_MAXLEN-4))
				{
					tty_recv_stat = TTY_HEADER1;
				}
			}
			break;
		
		case TTY_0A:
			if(dat == 0x0au)
			{
				tty_isrbuf[count] = 0;
				if(TTYRecv_qhd != NULL)
				{
					xQueueSendFromISR(TTYRecv_qhd, &tty_isrbuf, NULL);
				}
			}
			tty_recv_stat = TTY_HEADER1;
			break;
		
		default:
			tty_recv_stat = TTY_HEADER1;
			break;
	}
}

void Terminal_BreakIsr(void)
{
	tty_recv_stat = TTY_HEADER1;
}
